package com.music.client.playlist.client.impl;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.HttpException;
import org.springframework.beans.factory.annotation.Required;

import com.music.client.playlist.client.PlaylistClient;
import com.music.client.playlist.constants.PlaylistConstants;
import com.music.service.playlists.beans.Playlist;
import com.music.service.playlists.exceptions.InvalidUrlException;
import com.music.service.playlists.service.PlaylistService;
import com.music.service.songs.beans.Song;
import com.music.service.songs.service.SongService;
import com.music.service.urls.beans.Url;
import com.music.service.urls.service.UrlService;
import com.music.urlValidator.MusicValidator;

public class PlaylistClientImpl implements PlaylistClient {

	private PlaylistService mPlaylistService;
	private SongService mSongService;
	private UrlService mUrlService;
	private MusicValidator mMusicValidator;
	
	@Override
	public Playlist addPlaylist(Playlist pPlaylistId) {
		return  getPlaylistService().addPlaylist(pPlaylistId);
	}

	@Override
	public void addSongToPlaylist(Playlist pPlaylist, Song pSong) {
		 getPlaylistService().addSongToPlaylist(pPlaylist,pSong);
	}

	@Override
	public void deletePlaylist(Playlist pPlaylist) {
		getPlaylistService().deletePlaylist(pPlaylist);
	}

	@Override
	public void deleteSongFromPlaylist(Playlist pPlaylist, Song pSong) {
		 getPlaylistService().deleteSongFromPlaylist(pPlaylist,pSong);
	}

	@Override
	public List<Playlist> viewPlaylists(Long pMemberId) {
		return getPlaylistService().viewPlaylists(pMemberId);
	}

	

	@Override
	public List<Playlist> getRecentPlaylists(Long pMemberId) {
		return getRecentPlaylists(pMemberId, PlaylistConstants.RECENT_PLAYLISTS_SIZE);
	}
	
	public List<Playlist> getRecentPlaylists(Long pMemberId, int pSize) {
		return getPlaylistService().getRecentPlaylists(pMemberId, pSize);
	}

	
	public Playlist addSongToPlaylist(Long pMemberId,Long pPlaylistId,String pSongName,String pUrl) throws IllegalAccessException, HttpException, IOException, InvalidUrlException ,Exception{
		
		Playlist playlist = getPlaylistInfoForMember(pMemberId, pPlaylistId);
		
		if( playlist == null){
			throw new IllegalAccessException("You are not allowed to add song to playlist");
		}
		 
		boolean isValidUrl = getMusicValidator().isValid(pUrl);
		
		if(!isValidUrl){
			throw new InvalidUrlException("Not valid music url");
		}
		
		Song song = new Song();
		song.setCreatedMemberId(pMemberId);
		song.setName(pSongName);
		
		Url url = new Url();
		url.setCreatedMemberId(pMemberId);
		url.setUrlPath(pUrl);
		//To maintain transaction, we are creating row in songs and url table using playlistService itself.
		song = getPlaylistService().addSongToPlaylist(playlist, song, url);
		
		addSongToPlaylist(playlist,song);
		
		return playlist;
		
		
		
	}
	
	public Playlist getPlaylistSongsForMember(Long pMemberId, Long pPlaylistId) {
		Playlist playlist = null;
		playlist = getPlaylistService().getPlaylistInfoForMember(pMemberId, pPlaylistId);
		if(playlist == null){
			return null;
		}
		List<Song> songs = getSongService().getSongsFromPlaylist(playlist);
		
		if(songs == null || songs.isEmpty()){
			return playlist;
		}
		for(Song song:songs){
			playlist.addSong(song);
		}
		
		List<Long> urls = getSongService().getUrlsForSongsForMember(pMemberId, playlist.getSongIds());
		Set<Long> urlsSet = new HashSet<Long>(urls);
		
		Map<Long, Url> songIdurlMap = getUrlService().getUrlSongIdMap(urlsSet);
		
		
		if(songIdurlMap == null || songIdurlMap.isEmpty()){
			//throw new UrlUnknownException();
		}
		for(Song song:songs){
			song.setUrl(songIdurlMap.get(song.getSongId()));
		}
		return playlist;
	}

	
	public Playlist getPlaylistInfoForMember(Long pMemberId, Long pPlaylistId) {
		return getPlaylistService().getPlaylistInfoForMember(pMemberId, pPlaylistId);
	}

	public Playlist editPlaylist(Playlist pPlaylist) {
		return getPlaylistService().editPlaylist(pPlaylist);
		
	}


	/**
	 * @return the songService
	 */
	public SongService getSongService() {
		return mSongService;
	}

	/**
	 * @param pSongService the songService to set
	 */
	@Required
	public void setSongService(SongService pSongService) {
		mSongService = pSongService;
	}

	/**
	 * @return the urlService
	 */
	public UrlService getUrlService() {
		return mUrlService;
	}

	/**
	 * @param pUrlService the urlService to set
	 */
	@Required
	public void setUrlService(UrlService pUrlService) {
		mUrlService = pUrlService;
	}

	/**
	 * @return the playlistClient
	 */
	public PlaylistService getPlaylistService() {
		return mPlaylistService;
	}

	/**
	 * @param pPlaylistService the playlistClient to set
	 */
	@Required
	public void setPlaylistService(PlaylistService pPlaylistService) {
		mPlaylistService = pPlaylistService;
	}

	/**
	 * @return the musicValidator
	 */
	public MusicValidator getMusicValidator() {
		return mMusicValidator;
	}

	/**
	 * @param pMusicValidator the musicValidator to set
	 */
	@Required
	public void setMusicValidator(MusicValidator pMusicValidator) {
		mMusicValidator = pMusicValidator;
	}

		

}
